#pragma once

/*
// This class makes it easy to use Lua; its a wrapper class
// Type: Singleton
*/

/* Include LUA */
extern "C" {
#include "Lua/Implementation/lua.h"
#include "Lua/Implementation/lauxlib.h"
#include "Lua/Implementation/lualib.h"
}

// Included our libraries
#pragma comment(lib, "lua5.1.lib")
#pragma comment(lib, "lua51.lib")

#include <iostream>
#include <string>
using namespace std;

/* Defines */

/* Lua Debug Defines; if commented out it will stop Lua from putting debug information into that location */
#define LUA_CONSOLE_DEBUG		// Send Lua debug information to the console
#define LUA_EXECUTE_DEBUG		// Send Lua debug information to the execution log

#ifdef LUA_EXECUTE_DEBUG
#include "ExecutionLog.h"
#endif

#define Lua cLua::Instance()

#define LuaGlue extern "C" int
extern "C" {
typedef int (*LuaFunctionType)(struct lua_State *pLuaState);
};

class cLua
{
private:
	cLua();
	cLua(const cLua&);
	cLua& operator =(const cLua&);
	~cLua();


	lua_State	*m_pScriptContext;
	void(*m_pErrorHandler)(const char *pError);



public:
	static cLua* Instance();


	bool		RunScript(const char *pFilename);
	bool		RunString(const char *pCommand);
	const char *GetErrorString(void);
	bool		AddFunction(const char *pFunctionName, LuaFunctionType pFunction);
	const char *GetStringArgument(int stack_location, const char *pDefault=NULL); // num -> stack position, pDefault -> the default
	double		GetNumberArgument(int stack_location, double dDefault=0.0); // num -> stack pos, dDefault -> the default
	bool		GetBooleanArgument(int stack_location);
	void		PushString(const char *pString);
	void		PushNumber(double value);

	void		SetGlobalNum(string name, double val);
	void		SetGlobalStr(string name, string val);

	bool		IsNumber(int stack_location) {return (lua_isnumber(m_pScriptContext, stack_location) != 0);}
	bool		IsString(int stack_location) {return (lua_isstring(m_pScriptContext, stack_location) != 0);}
	int			GetParamaterCount() {return lua_gettop(m_pScriptContext);}

	void		SetErrorHandler(void(*pErrHandler)(const char *pError)) {m_pErrorHandler = pErrHandler;}

	lua_State	*GetScriptContext(void)		{return m_pScriptContext;}

	double		GetGlobalNum(string name, double dDefault=0.0);
	const char *GetGlobalStr(string name, const char *pDefault=NULL);


};